/**
 * @file engineer_mode_connectivity.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "lv_watch.h"

#if USE_LV_WATCH_ENGINEER_MODE!= 0

#ifndef BUILD_IN_PC_SIMULATOR
#if USE_LV_WLAN != 0
#include "../lvgl/hal/dm/libhttpclient.h"
#endif
#endif

/*********************
 *      DEFINES
 *********************/
#define ENGINEER_MODE_CONNECTIVITY_LIST_CNT    1

/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static void connectivity_btn_rel_event_cb(lv_obj_t * btn, lv_event_t e);
static void wifi_test_start(lv_obj_t * btn, lv_event_t event);
static void wifi_create(lv_obj_t * par);
static void connectivity_prepare_destory(lv_obj_t * activity_obj);

/**********************
 *  STATIC VARIABLES
 **********************/
const lv_engineer_item_t engineer_mode_connectivity_list[] = {
    { WATCH_TEXT_ID_EMODE_CONN_WIFI, wifi_create, NULL },
};

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
***********************/
lv_obj_t * engineer_mode_connectivity_create(lv_obj_t * activity_obj)
{
    lv_obj_t * obj;
    if(activity_obj == NULL) {
        lv_watch_activity_ext_t activity_ext;
        memset(&activity_ext, 0, sizeof(lv_watch_activity_ext_t));
        activity_ext.actId = ACT_ID_ENGINEER_MODE_CONNECTIVITY;
        activity_ext.create = engineer_mode_connectivity_create;
        activity_ext.prepare_destory = connectivity_prepare_destory;
        activity_obj = lv_watch_creat_activity_obj(&activity_ext);
        LV_ASSERT_MEM(activity_obj);
        if(NULL == activity_obj) {
            return NULL;
        }
    }

    obj = lv_watch_obj_create(activity_obj);
    LV_ASSERT_MEM(obj);
    if(NULL == obj) {
        return NULL;
    }
    lv_engineer_connectivity_obj_ext_t * conn_ext
        = lv_obj_allocate_ext_attr(obj, sizeof(lv_engineer_connectivity_obj_ext_t));
    LV_ASSERT_MEM(conn_ext);

    lv_obj_t * title = lv_label_create(obj, NULL);
    lv_obj_set_size(title, LV_HOR_RES, LV_VER_RES / 4);
    lv_label_set_text_id(title, WATCH_TEXT_ID_ENGINEER_MODE_CONNECTIVITY);
    lv_obj_add_style(title, LV_LABEL_PART_MAIN, &lv_watch_font30);
    lv_obj_align(title, NULL, LV_ALIGN_IN_TOP_MID, 0, 5);

    lv_obj_t * list = lv_list_create(obj, NULL);
    lv_obj_set_size(list, LV_HOR_RES, LV_VER_RES - lv_obj_get_height(title) - 10);
    lv_page_set_edge_flash(list, true);
    lv_obj_add_style(list, LV_LIST_PART_EDGE_FLASH, &lv_watch_cont_opa1);
    lv_obj_align(list, title, LV_ALIGN_OUT_BOTTOM_MID, 0, 20);

    lv_engineer_main_obj_ext_t * ext = engineer_mode_get_ext();
    lv_obj_add_style(list, LV_LIST_PART_BG,  &lv_watch_style_transp);

    lv_watch_obj_add_element(list);
    lv_watch_obj_add_element(lv_page_get_scrollable(list));

    uint8_t i = 0;
    lv_obj_t * btn;
    lv_obj_t * label;
    for(i = 0; i < ENGINEER_MODE_CONNECTIVITY_LIST_CNT; i++) {
        btn = lv_list_add_btn(list, NULL, lv_lang_get_text(engineer_mode_connectivity_list[i].txtId));
        lv_watch_set_free_num(btn, i);
        lv_obj_add_style(btn, LV_BTN_PART_MAIN, &(ext->list_btn_st));
        lv_obj_set_style_local_border_side(btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_BORDER_SIDE_NONE);
        lv_obj_set_style_local_border_side(btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, LV_BORDER_SIDE_NONE);
        lv_obj_set_style_local_border_side(btn, LV_BTN_PART_MAIN, LV_STATE_FOCUSED, LV_BORDER_SIDE_NONE);
        lv_obj_set_event_cb(btn, connectivity_btn_rel_event_cb);

        label = lv_obj_get_child(btn, NULL);
        lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
        lv_label_set_long_mode(label, LV_LABEL_LONG_BREAK);
        lv_obj_set_width(label, LV_HOR_RES - 10);
    }

    lv_obj_set_click(list, true);

    return obj;
}


/**********************
 *   STATIC FUNCTIONS
 **********************/
static lv_engineer_connectivity_obj_ext_t * connectivity_get_ext(void)
{
    lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_ENGINEER_MODE_CONNECTIVITY);
    if(NULL == activity_obj) return NULL;

    lv_obj_t * obj = NULL;
    lv_watch_get_child_obj(activity_obj, lv_watch_obj_signal, &obj);

    if(obj) {
        void * ext = lv_obj_get_ext_attr(obj);
        return ext;
    }
    return NULL;
}

static void connectivity_btn_rel_event_cb(lv_obj_t * btn, lv_event_t e)
{
    if(LV_EVENT_CLICKED == e) {
        uint32_t num = lv_obj_get_user_data(btn).user_num;
        lv_obj_t * obj = NULL;

        obj = engineer_mode_item_watch_obj_create(NULL, engineer_mode_connectivity_list[num].item_prepare_destory);
        if(NULL == obj) {
            printf("%s: obj is null\n", __FUNCTION__);
        } else {
            lv_engineer_connectivity_obj_ext_t * ext = connectivity_get_ext();
            ext->wifi_obj = obj;
            engineer_mode_item_title_create(obj, engineer_mode_connectivity_list[num].txtId);
            engineer_mode_connectivity_list[num].item_content_create(obj);
        }
    }
}

#ifndef BUILD_IN_PC_SIMULATOR
#if USE_LV_WLAN != 0
static size_t write_data(void * buf, size_t size, size_t nmemb, void * userp)
{
    printf("%s buf \n%s\n", __FUNCTION__, (char *)buf);
    return size;
}

static void wifi_test_over_task_cb(lv_task_t * task)
{
    lv_engineer_connectivity_obj_ext_t * ext = connectivity_get_ext();
    if(NULL == ext) return;

    lv_obj_t * label = lv_obj_get_child(ext->wifi_obj, NULL);
    if(1 == lv_watch_get_free_num(label)) {
        lv_label_set_text_id(label, WATCH_TEXT_ID_SEND_SUCCESS);
    } else {
        lv_label_set_text_id(label, WATCH_TEXT_ID_SEND_FAILED);
    }
    lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, lv_obj_get_height(label));

    lv_obj_t * btn = lv_obj_get_child(ext->wifi_obj, label);
    lv_obj_set_click(btn, true);
    lv_btn_toggle(btn);
}

static void wifi_test_task_cb(lv_task_t * task)
{
    lv_engineer_connectivity_obj_ext_t * ext = connectivity_get_ext();
    if(NULL == ext) return;

    lv_obj_t * label = lv_obj_get_child(ext->wifi_obj, NULL);

    char * userp  = malloc(3000);
    struct http_client * client = http_client_init();
    char url[] = "https://www.baidu.com";
    int32_t response_code;

    http_client_setopt(client, HTTPCLIENT_OPT_URL, url);
    http_client_setopt(client, HTTPCLIENT_OPT_HTTP1_0, 0);	/*"0" is HTTP 1.1, "1" is HTTP 1.0 */
    http_client_setopt(client, HTTPCLIENT_OPT_RESPONSECB, write_data);	/*response callback */
    http_client_setopt(client, HTTPCLIENT_OPT_RESPONSECB_DATA, userp);	/*response callback arg*/
    http_client_setopt(client, HTTPCLIENT_OPT_METHOD, HTTPCLIENT_REQUEST_GET);	/*set method,support GET/POST/PUT */

    response_code = http_client_perform(client);	/*execute http send and recv */
    if (HTTP_CLIENT_OK != response_code) {
        printf("%s http perform have some wrong[%d]\n", __FUNCTION__, response_code);
        http_client_shutdown(client);	/*release http resources */
    }

    http_client_getinfo(client, HTTPCLIENT_GETINFO_RESPONSE_CODE, &response_code);
    printf("%s http perform response is 'HTTP OK'(%d)\n", __FUNCTION__, response_code);
    if (200 == response_code) {
        printf("%s http perform success %d\n", __FUNCTION__, response_code);
        lv_watch_set_free_num(label, 1);
    } else {
        printf("%s http perform failed %d\n", __FUNCTION__, response_code);
        lv_watch_set_free_num(label, 0);
    }

    lv_task_t * over_task = lv_task_create(wifi_test_over_task_cb, 500, LV_TASK_PRIO_HIGH, NULL);
    lv_task_once(over_task);
}
#endif
#endif

static void wifi_test_start(lv_obj_t * btn, lv_event_t event)
{
    if(LV_EVENT_CLICKED != event) return;

    lv_obj_t * par = lv_obj_get_parent(btn);
    lv_obj_t * label = lv_obj_get_child_back(par, btn);

#ifndef BUILD_IN_PC_SIMULATOR
#if USE_LV_WLAN != 0
    hal_wlan_info_t * info = hal_wlan_get_info();
    if(info) {
        if(info->proc.ap && (HAL_WLAN_AP_STATE_ACT == info->proc.proc_state)) {
            printf("%s: http test\n", __FUNCTION__);
            lv_label_set_text_id(label, WATCH_TEXT_ID_EMODE_SENDING_DATA);
            lv_obj_align(label, par, LV_ALIGN_CENTER, 0, lv_obj_get_height(label));
            lv_obj_set_click(btn, false);
            lv_btn_toggle(btn);

            lv_task_t * task = lv_task_create(wifi_test_task_cb, 50, LV_TASK_PRIO_HIGH, NULL);
            lv_task_once(task);
            return;
        }
    }
#endif
#endif

    printf("%s: wifi is not connected\n", __FUNCTION__);
    lv_label_set_text_id(label, WATCH_TEXT_ID_EMODE_WIFI_NOT_CONN);
    lv_obj_align(label, par, LV_ALIGN_CENTER, 0, lv_obj_get_height(label));
}

static void wifi_create(lv_obj_t * par)
{
    lv_obj_t * btn = lv_btn_create(par, NULL);
    lv_obj_add_style(btn, LV_BTN_PART_MAIN, &lv_style_pretty);
    lv_obj_set_style_local_text_color(btn, LV_BTN_PART_MAIN, LV_STATE_CHECKED, LV_COLOR_GRAY);
    lv_btn_set_fit2(btn, LV_FIT_NONE, LV_FIT_TIGHT);
    lv_obj_set_width(btn, lv_obj_get_width(par) / 2);
    lv_obj_set_event_cb(btn, wifi_test_start);
    lv_watch_obj_add_element(btn);

    lv_obj_t * label = lv_label_create(btn, NULL);
    lv_label_set_text_id(label, WATCH_TEXT_ID_START_TEST);

    lv_obj_align(btn, par, LV_ALIGN_CENTER, 0, -lv_obj_get_height(btn));

    label = lv_label_create(par, NULL);
    lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
    lv_label_set_long_mode(label, LV_LABEL_LONG_BREAK);
    lv_obj_set_width(label, lv_obj_get_width(par) - 40);
    lv_label_set_text(label, "");
    lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, lv_obj_get_height(label));
}

static void connectivity_prepare_destory(lv_obj_t * activity_obj)
{
    lv_watch_png_cache_all_free();
}

#endif /*USE_LV_WATCH_ENGINEER_MODE*/
